/**
 * ReportGear(2011)
 */
package com.reportgear.report.model.calculator;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.reportgear.report.model.ReportModel;
import com.reportgear.report.model.cell.Cell;
import com.reportgear.report.model.cell.value.CrossDataObject;
import com.reportgear.report.model.cell.value.salary.SalaryFormulaObject;
import com.reportgear.report.model.cell.value.salary.SalaryItemObject;
import com.reportgear.report.model.cell.value.salary.SalaryMainObject;
import com.reportgear.report.model.cell.value.support.CommonObject;
import com.sot.core.util.NumberUtils;
import com.sot.core.util.StringUtils;

/**
 * 
 * 生成交叉数据对象,不计算值
 * 
 * @version 1.0 2011-4-10
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class CrossDataObjectCalculator extends AbstractCalculator {
	// 表达式分隔符号
	private static final String REG_EXPRESS_DELIMETER = "[+|-|*|/]";

	public CrossDataObjectCalculator() {

	}

	@Override
	public ReportModel calculate(ReportModel model, CalcParameter parameter) {
		if (logger.isDebugEnabled()) {
			logger.debug("计算模型：电信薪酬对象计算");
		}

		ReportModel calcModel = model;

		this.doCalculate(calcModel);

		return calcModel;
	}

	/**
	 * 计算模型
	 * 
	 * @param model
	 *            模型
	 * @param mainObjList
	 *            Id列表
	 */
	private void doCalculate(ReportModel model) {
		for (Iterator<Cell> i = model.getCellIterator(); i.hasNext();) {
			Cell cell = i.next();

			if (cell.getColumn() > 0 && cell.getRow() > 0) {
				this.calculateCell(model, cell);
			}
		}

		this.calculateItemCell(model);
		this.calculateFormulaItemCell(model);
	}

	/**
	 * 所有SalaryFormulaObject对象Cell转换为CrossDataObject对象
	 * 
	 * @param model
	 *            模型
	 * @param mainObjList
	 *            主对象Id列表
	 */
	private void calculateFormulaItemCell(ReportModel model) {
		for (Iterator<Cell> iter = model.getCellsIteratorByCellElementClass(SalaryFormulaObject.class); iter.hasNext();) {
			Cell cell = iter.next();

			// TODO 要优化，可以先计算区域
			// 计算X值(薪酬项目),只要上面Cell为SalaryItemObject或SalaryFormulaObject则为计算项目,基本可很快就找到
			int row = cell.getRow();
			int col = cell.getColumn();
			String formula = "";
			Set<Integer> x = new HashSet<Integer>();
			formula = ((SalaryFormulaObject) cell.getValue()).getFormula();
			if (!StringUtils.isEmpty(formula)) {
				String[] sids = formula.split(REG_EXPRESS_DELIMETER);
				for (String sid : sids) {
					// 项目的格式为：项目名(项目Id)
					int index1 = sid.indexOf('[');
					int index2 = sid.indexOf(']');
					if ((index1 > 1) && (index2 > 0)) {
						x.add(NumberUtils.convertToInteger(sid.substring(index1 + 1, index2), 0));
					}
				}
			}

			// 计算Y值
			int y = 0;
			for (int i = 0; i < col; i++) {
				Object v = model.getCell(i, row).getValue();

				if (v == null) {
					continue;
				}

				if (v instanceof SalaryMainObject) {
					CommonObject smo = ((SalaryMainObject) v).getObject();
					y = smo.getId();
					break;
				}
			}

			if (y == 0) {
				return;
			}
			
			CrossDataObject cdo = new CrossDataObject();
			cdo.getxIds().addAll(x);
			cdo.setY(y);
			cdo.setXFormula(formula);

			cell.setValue(cdo);
		}
	}

	/**
	 * 所有SalaryItemObject对象Cell转换为CrossDataObject对象
	 * 
	 * @param model
	 *            模型
	 */
	private void calculateItemCell(ReportModel model) {
		for (Iterator<Cell> iter = model.getCellsIteratorByCellElementClass(SalaryItemObject.class); iter.hasNext();) {
			Cell cell = iter.next();

			int row = cell.getRow();
			int col = cell.getColumn();
			String formula = "";
			Set<Integer> x = new HashSet<Integer>();
			x.add(((SalaryItemObject) cell.getValue()).getItem().getId());

			// 计算Y值
			int y = 0;
			for (int i = 0; i < col; i++) {
				Object v = model.getCell(i, row).getValue();

				if (v == null) {
					continue;
				}

				if (v instanceof SalaryMainObject) {
					CommonObject smo = ((SalaryMainObject) v).getObject();
					y = smo.getId();

					break;
				}
			}

			if( y==0){
				return;
			}
			
			CrossDataObject cdo = new CrossDataObject();
			cdo.getxIds().addAll(x);
			cdo.setY(y);
			cdo.setXFormula(formula);

			cell.setValue(cdo);
		}
	}

	/**
	 * 单元格计算
	 * 
	 * @param model
	 *            模型
	 * @param cell
	 *            单元格
	 */
	private void calculateCell(ReportModel model, Cell cell) {
		// 只计算空单元格
		if (cell != null && !StringUtils.isEmpty(cell.getValue())) {
			return;
		}

		// TODO 要优化，可以先计算区域
		// 计算X值(薪酬项目),只要上面Cell为SalaryItemObject或SalaryFormulaObject则为计算项目,基本可很快就找到
		int row = cell.getRow();
		int col = cell.getColumn();
		String formula = "";
		Set<Integer> x = new HashSet<Integer>();
		for (int i = 0; i < row; i++) {
			Object v = model.getCell(col, i).getValue();
			if (v == null) {
				continue;
			}

			if (v instanceof SalaryItemObject) {
				x.add(((SalaryItemObject) v).getItem().getId());
				break;
			}

			if (v instanceof SalaryFormulaObject) {
				formula = ((SalaryFormulaObject) v).getFormula();
				if (!StringUtils.isEmpty(formula)) {
					String[] sids = formula.split(REG_EXPRESS_DELIMETER);
					for (String sid : sids) {
						// 项目的格式为：项目名(项目Id)
						int index1 = sid.indexOf('[');
						int index2 = sid.indexOf(']');
						if ((index1 > 1) && (index2 > 0)) {
							x.add(NumberUtils.convertToInteger(sid.substring(index1 + 1, index2), 0));
						}
					}
				}

				break;
			}
		}

		if (x.isEmpty()) {
			return;
		}

		// 计算Y值
		int y = 0;
		for (int i = 0; i < col; i++) {
			Object v = model.getCell(i, row).getValue();

			if (v == null) {
				continue;
			}

			if (v instanceof SalaryMainObject) {
				CommonObject smo = ((SalaryMainObject) v).getObject();
				y = smo.getId();

				break;
			}
		}

		if (y == 0) {
			return;
		}

		CrossDataObject cdo = new CrossDataObject();
		cdo.getxIds().addAll(x);
		cdo.setY(y);
		cdo.setXFormula(formula);

		cell.setValue(cdo);
	}
}
